package com.lovo.manage_back.interceptor;

import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lovo.manage_back.bean.User;
import com.lovo.manage_back.result.GlobalHandleException;
import com.lovo.manage_back.result.Result;
import com.lovo.manage_back.result.ResultCode;
import com.lovo.manage_back.result.UserValid;
import com.lovo.manage_back.service.UserService;
import com.lovo.manage_back.util.JWTUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.lang.reflect.Method;

@Component
public class JWTInterceptor implements HandlerInterceptor {
    @Autowired
    private UserService userService;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

            String token = request.getHeader("Authorization");// 从 http 请求头中取出 token

            // 如果不是映射到方法直接通过
            if(!(handler instanceof HandlerMethod)){
                return true;
            }
            HandlerMethod handlerMethod=(HandlerMethod)handler;
            Method method=handlerMethod.getMethod();
            //检查是否有UserValid注释，没有则跳过认证
            if(!method.isAnnotationPresent(UserValid.class)
                    && !handlerMethod.getBeanType().isAnnotationPresent(UserValid.class)){
                return true;
            }
            if(token == null){
                writeValueAsString(response, Result.fail(ResultCode.USER_NOT_LOGGED_IN));
                return false;
            }
            String username;
            try {
                if(!token.startsWith("Bearer ")){
                    writeValueAsString(response, Result.fail(ResultCode.USER_NOT_LOGGED_IN));
                    return false;
                }
                token = token.substring(7);
                username = JWTUtil.getAudience(token);
            } catch (GlobalHandleException | NumberFormatException e) {
                writeValueAsString(response, Result.fail(ResultCode.USER_NOT_LOGGED_IN));
                return false;
            }
            User user = userService.getUserByName(username);
            if(user == null){
                writeValueAsString(response,Result.fail(ResultCode.USER_NOT_EXIST));
                return false;
            }
            // 验证 token
            try {
                JWTUtil.verifyToken(token,user.getPwd());
            } catch (GlobalHandleException e) {
                writeValueAsString(response,Result.fail(ResultCode.USER_AUTHENTICATION_ERROR));
                return false;
            }
            request.setAttribute("user",user);
            return true;


    }
    private void writeValueAsString(HttpServletResponse response, Result result) throws IOException {

        ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().print(mapper.writeValueAsString(result));


    }

}
